#ifndef _SCUDB_THREAD_H_
#define _SCUDB_THREAD_H_
#include "sd_global.h"
#include <pthread.h>

#ifndef sd_getCurrentThreadID
#ifdef PTW32_VERSION
#include <windows.h>
#define sd_getCurrentThreadID() ((uint32)GetCurrentThreadId())
#else
#define sd_getCurrentThreadID() ((uint32)pthread_self())
#endif
#endif


/* Definition of sd_Mutex from thread */
typedef pthread_mutex_t sd_Mutex;
#define sd_MutexInit(mutex) pthread_mutex_init(mutex, NULL)
#define sd_MutexDestroy(mutex) pthread_mutex_destroy(mutex)
#define sd_MutexLock(mutex) pthread_mutex_lock(mutex)
#define sd_MutexUnlock(mutex) pthread_mutex_unlock(mutex)

/* Definition of share lock and exclusive lock */
typedef pthread_rwlock_t sd_RWLock;
/* Definition of spin lock */
typedef pthread_mutex_t sd_SpinLock;

#ifdef _DEBUG_PTHREAD
void sd_SpinLock_Init(sd_SpinLock* lock);
void sd_SpinLock_Destroy(sd_SpinLock* lock);
void sd_SpinLock_Lock(sd_SpinLock* lock);
void sd_SpinLock_Unlock(sd_SpinLock* lock);

sd_Ret sd_RWLock_Init(sd_RWLock* lock);
sd_Ret sd_RWLock_Destroy(sd_RWLock* lock);
sd_Ret sd_RWLock_RLock(sd_RWLock* lock);
sd_Ret sd_RWLock_WLock(sd_RWLock* lock);
sd_Ret sd_RWLock_Unlock(sd_RWLock* lock);
sd_Ret sd_RWLock_TryRLock(sd_RWLock* lock);
sd_Ret sd_RWLock_TryWLock(sd_RWLock* lock);
sd_Ret sd_RWLock_TimeoutRLock(sd_RWLock* lock, const struct timespec* timout);
sd_Ret sd_RWLock_TimeoutWLock(sd_RWLock* lock, const struct timespec* timout);

#else

#define sd_SpinLock_Init(lock) pthread_mutex_init(lock, NULL)
#define sd_SpinLock_Destroy(lock) pthread_mutex_destroy(lock)
#define sd_SpinLock_Lock(lock) pthread_mutex_lock(lock)
#define sd_SpinLock_Unlock(lock) pthread_mutex_unlock(lock)
/*
#define sd_SpinLock_Init(lock) pthread_spin_init(lock, PTHREAD_PROCESS_PRIVATE)
#define sd_SpinLock_Destroy(lock) pthread_spin_destroy(lock)
#define sd_SpinLock_Lock(lock) pthread_spin_lock(lock)
#define sd_SpinLock_Unlock(lock) pthread_spin_unlock(lock)
*/

#define sd_RWLock_Init(lock) pthread_rwlock_init(lock, NULL)
#define sd_RWLock_Destroy(lock) pthread_rwlock_destroy(lock)
#define sd_RWLock_RLock(lock) pthread_rwlock_rdlock(lock)
#define sd_RWLock_WLock(lock) pthread_rwlock_wrlock(lock)
#define sd_RWLock_Unlock(lock) pthread_rwlock_unlock(lock)
#define sd_RWLock_TryRLock(lock) (pthread_rwlock_tryrdlock(lock) == EBUSY ? SD_RET_LOCK_BUSY:SD_RET_OK)
#define sd_RWLock_TryWLock(lock) (pthread_rwlock_trywrlock(lock) == EBUSY ? SD_RET_LOCK_BUSY:SD_RET_OK)
//#define sd_RWLock_TimeoutRLock(lock, timout) (pthread_rwlock_timedrdlock(lock, timout) == ETIMEDOUT ? SD_RET_LOCK_BUSY:SD_RET_OK)
//#define sd_RWLock_TimeoutWLock(lock, timout) (pthread_rwlock_timedwrlock(lock, timout) == ETIMEDOUT ? SD_RET_LOCK_BUSY:SD_RET_OK)

#endif

sd_Ret sd_RWLock_TimeoutRLock(sd_RWLock* lock, const struct timespec* timeout);
sd_Ret sd_RWLock_TimeoutWLock(sd_RWLock* lock, const struct timespec* timeout);

/* Definition of the thread's re-scheduling */
#define sd_sched_yield sched_yield

#endif

